package org.rcy.framework.utils.json;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;

public class JsonUtils {

	private static Logger logger = LoggerFactory.getLogger(JsonUtils.class);

	private static ObjectMapper mapper = new ObjectMapper();
	static{
		mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
		mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
		mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
		//根据属性序列化
		mapper.setVisibility(
				mapper.getSerializationConfig().
				getDefaultVisibilityChecker().
				withFieldVisibility(JsonAutoDetect.Visibility.ANY).
				withGetterVisibility(JsonAutoDetect.Visibility.NONE));
		
		SimpleModule module = new SimpleModule();
		module.addSerializer(Long.class, new ToStringSerializer());
		mapper.registerModule(module);
	}
	
	/**
	 * 返回json字符串
	 * @param object
	 * @return
	 * @throws IOException
	 */
	public static String toJson(Object object) throws IOException {
		return mapper.writeValueAsString(object);
	}

	/**
	 * 返回json字符串，不抛出异常
	 * @param object
	 * @return
	 */
	public static String convertJson(Object object){
		if(object == null) {
			return null;
		}
		try {
			return mapper.writeValueAsString(object);
		} catch (JsonProcessingException e) {
			logger.warn("JsonUtils toJsonStr error {}",e.getMessage(),e);
			return null;
		}
	}

	/**
	 * 返回格式化json字符串 不抛出异常，异常情况喜爱返回null
	 * @param object
	 * @return
	 */
	public static String toJsonPretty(Object object){
		try {
			return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
		} catch (Exception e) {
			logger.warn("JsonUtils toJsonPretty error {}",e.getMessage(),e);
			return null;
		}
	}

	public static <T> T parseObject(String text, Class<? extends T> clazz) throws IOException {
		return mapper.readValue(text, clazz);
	}

	public static <T> T parseObject(String text, TypeReference<T> typeReference) throws IOException {
		return mapper.readValue(text, typeReference);
	}

	public static byte[] toJsonBytes(Object object) throws IOException {
		return mapper.writeValueAsBytes(object);
	}
	
	public static <T> T parseArray(String text, TypeReference<T> typeReference) throws IOException {
		return mapper.readValue(text,typeReference);
	}
	
	public static <T> List<T> parseArray(String text, Class<T> clazz) throws IOException {
		JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class,  clazz);
		return mapper.readValue(text,javaType);
	}
	
	public static JsonNode parseTree(String text) throws IOException {
		return mapper.readTree(text);
	}
}